package com.wskeee.ec.components
{
	import com.wskeee.ec.components.list.List;
	import com.wskeee.ec.components.skin.ComboBoxSkin;
	import com.wskeee.ec.interfaces.IComboBox;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.TextField;
	
	public class ComboBox extends BasePanel implements IComboBox
	{
		public function ComboBox()
		{
			super();
			width = 100;
			height = 20;
			border=false;
			shadow = false;
		}
		//--------------------------------------------------------------------------
		//
		//  variable
		//
		//--------------------------------------------------------------------------
		private var _openPosition:String = "bottom";
		
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		//---------------------
		//labelField 
		//---------------------
		/**
		 * 选择列表item显示label和选择item显示label 
		 * @param value
		 * 
		 */
		private var _labelField:String = "label";
		private var labelFieldChanged:Boolean = false;

		public function set labelField(value:String):void
		{
			if(_labelField!=value)
			{
				_labelField = value;
				labelFieldChanged = true;
				invalidateProperties();
			}
		}
		
		public function get labelField():String
		{
			return _labelField;
		}
		
		//---------------------
		//itemRenderer
		//---------------------
		/**
		 * 设置显示列表 list 的 itemRenderer 
		 * @param value
		 * 
		 */		
		private var _itemRenderer:Class;
		public function set itemRenderer(value:Class):void
		{
			if(_itemRenderer!=value)
				_itemRenderer = value;
		}
		
		public function get itemRenderer():Class
		{
			return _itemRenderer;
		}
		
		//---------------------
		//dataProvider
		//---------------------
		/**
		 * 显示列表数据 
		 * @param value
		 * 
		 */		
		private var _dataProvider:Object;
		private var dataProviderChanged:Boolean = false;
		public function set dataProvider(value:Object):void
		{
			_dataProvider = value;
			dataProviderChanged = true;
			invalidateProperties();
		}
		
		public function get dataProvider():Object
		{
			return _dataProvider;
		}
		
		//---------------------
		//selectedItem
		//---------------------
		/**
		 * 返回当前选择值，在可编辑状态下，当前用户输入操作后，selectedItem 为空。value 为用户所输入
		 * @return 
		 * 
		 */		
		public function get selectedItem():Object
		{
			if(!_dataProvider || _selectedIndex == -1)return null;
			return dataProvider[_selectedIndex];
		}
		
		//---------------------
		//selectedIndex
		//---------------------
		/**
		 * 设置 选择 dataProvider 索引值 
		 */
		private var _selectedIndex:int = -1;
		private var selectedIndexChanged:Boolean = false;
		public function set selectedIndex(value:int):void
		{
			if(dataProvider && value>=-1 && value<dataProvider.length && _selectedIndex!=value)
			{
				_selectedIndex = value;
				selectedIndexChanged = true;
				invalidateProperties();
				
				dispatchEvent(new Event(Event.CHANGE));
			}
		}
		public function get selectedIndex():int
		{
			return _selectedIndex;
		}
		
		//---------------------
		//editable
		//---------------------
		/**
		 * 设置可编辑 
		 * @param bo	true/false
		 * 
		 */		
		private var _editable:Boolean = false;
		private var editableChanged:Boolean = false;
		public function set editable(bo:Boolean):void
		{
			if(_editable!=bo)
			{
				_editable = bo;
				editableChanged = true;
				invalidateProperties();
			}
		}
		
		public function get editable():Boolean
		{
			return _editable;
		}
		
		//---------------------
		//restrict
		//---------------------
		/**
		 * 输入限制 
		 * @param value
		 * 
		 */		
		private var _restrict:String;
		private var restrictChanged:Boolean = false;
		public function set restrict(value:String):void
		{
			if(_restrict != value)
			{
				_restrict = value;
				restrictChanged = true;
				invalidateProperties();
			}
		}
		
		public function get restrict():String
		{
			return _restrict;
		}
		
		//---------------------
		//onInputOpen
		//---------------------
		private var inputOpenFlag:Boolean = false;
		private var _onInputOpen:Boolean = true;
		/**
		 * 输入进弹出列表 
		 */
		public function get onInputOpen():Boolean
		{
			return _onInputOpen;
		}
		
		/**
		 * @private
		 */
		public function set onInputOpen(value:Boolean):void
		{
			_onInputOpen = value;
		}
		//---------------------
		//isOpen
		//---------------------
		protected var _isOpen:Boolean = false;
		public function get isOpen():Boolean
		{
			return _isOpen;
		}
		
		/**
		 * 打开位置(top,bottom) 
		 */
		[Inspectable(type="String", enumeration="top,bottom", defaultValue="bottom")]
		public function get openPosition():String
		{
			return _openPosition;
		}
		
		/**
		 * @private
		 */
		public function set openPosition(value:String):void
		{
			_openPosition = value;
		}
		
		//-----------------------------------------------------------------
		//  children
		//-----------------------------------------------------------------
		//---------------------
		//openButton
		//---------------------
		public function get openButton():Button
		{
			return Object(skinDrawer).openButton;
		}
		
		//---------------------
		//labelFiled
		//---------------------
		public function get labelText():TextField
		{
			return Object(skinDrawer).labelText;
		}
		//--------------------------------------------------------------------------
		//
		//  style
		//
		//--------------------------------------------------------------------------
		override protected function initStyle():void
		{
			super.initStyle();
			defaultColor = getStyle("defaultColor");
			defaultAlpha = getStyle("defaultColorAlpha") as Number;
			rolloverColor = getStyle("rolloverColor");
			rolloverAlpha = getStyle("rolloverAlpha") as Number;
			selectedColor = getStyle("selectedColor");
			selectedAlpha = getStyle("selectedAlpha")  as Number;
		}
		//---------------------
		//itemHeight
		//---------------------
		/**
		 * 设置列表 的renderer 高
		 * @param value
		 * 
		 */		
		private var _itemHeight:Number=18;
		public function set itemHeight(value:Number):void
		{
			_itemHeight = value;
		}
		
		public function get itemHeight():Number
		{
			return _itemHeight;
		}
		
		//---------------------
		//defaultColor
		//---------------------
		/**
		 * 列表renderer 默认显示颜色 
		 * @param value
		 * 
		 */		
		public function set defaultColor(value:Object):void
		{
			setStyle("defaultColor", value);
		}
		public function get defaultColor():Object
		{
			return getStyle("defaultColor");
		}
		
		//---------------------
		//defaultColorAlpha
		//---------------------
		/**
		 * 列表 renderer 默认显示透明度
		 * @param value
		 * 
		 */		
		public function set defaultAlpha(value:Number):void
		{
			setStyle("defaultAlpha", value);
		}
		public function get defaultAlpha():Number
		{
			return getStyle("defaultAlpha") as Number;
		}
		
		//---------------------
		//rolloverColor
		//---------------------
		/**
		 * 列表renderer 鼠标移上去显示颜色 
		 * @param value
		 * 
		 */		
		public function set rolloverColor(value:Object):void
		{
			setStyle("rolloverColor", value);
		}
		public function get rolloverColor():Object
		{
			return getStyle("rolloverColor");;
		}
		
		//---------------------
		//rolloverColorAlpha
		//---------------------
		/**
		 * 列表renderer 鼠标移上去显示透明度
		 * @param value
		 * 
		 */	
		public function set rolloverAlpha(value:Number):void
		{
			setStyle("rolloverAlpha", value);
		}
		public function get rolloverAlpha():Number
		{
			return getStyle("rolloverAlpha") as Number;
		}
		
		//---------------------
		//selectedColor
		//---------------------
		/**
		 * 显示 renderer 鼠标选择后显示颜色 
		 * @param value
		 * 
		 */		
		public function set selectedColor(value:Object):void
		{
			setStyle("selectedColor", value);
		}
		public function get selectedColor():Object
		{
			return getStyle("selectedColor");
		}
		
		//---------------------
		//selectedColorAlpha
		//---------------------
		/**
		 * 显示renderer 鼠标选择后显示透明度 
		 * @param value
		 * 
		 */	
		public function set selectedAlpha(value:Number):void
		{
			setStyle("selectedAlpha", value);
		}
		
		public function get selectedAlpha():Number
		{
			return getStyle("selectedAlpha") as Number;
		}
		
		//--------------------------------------------------------------------------
		//
		//  init
		//
		//--------------------------------------------------------------------------
		
		//---------------------
		//initSkin
		//---------------------
		override protected function initSkin():void
		{
			super.initSkin();
			initLabelText();
			initOpenButton();
		}
		
		//--------------------------------------------------------------------------
		//
		//  public Method
		//
		//--------------------------------------------------------------------------
		//---------------------
		//open
		//---------------------
		private var openChanedFlag:Boolean = false;
		public function open():void
		{
			_isOpen = true;
			openChanedFlag = true;
			invalidateProperties();
		}
		
		//---------------------
		//close
		//---------------------
		public function close():void
		{
			removeList();
			openButton.selected = false;
			_isOpen = false;
		}
		
		//---------------------
		//destory
		//---------------------
		override public function destory():void
		{
			destoryOpenButton();
			super.destory();
		}
		
		//--------------------------------------------------------------------------
		//
		//  validate method
		//
		//--------------------------------------------------------------------------
		
		//---------------------
		//commitProperties
		//---------------------
		override protected function commitProperties():void
		{
			super.commitProperties();
			
			if(labelFieldChanged)
			{
				labelFieldChanged = false;
				selectedIndexChanged = true;
			}
			
			if(labelText)
			{
				if(restrictChanged)
				{
					restrictChanged = false;
					labelText.restrict = restrict;
				}
				if(editableChanged)
				{
					editableChanged = false;
					labelText.selectable = editable;
					labelText.mouseEnabled = editable;
				}
			}
			
			if(selectedIndexChanged)
			{
				selectedIndexChanged = false;
				if(labelText && _selectedIndex!=-1)
					labelText.text = selectedItem[labelField].toString();
			}
			
			if(inputOpenFlag)
			{
				inputOpenFlag = false;
				openChanedFlag = true;
			}
			
			if(openChanedFlag)
			{
				openChanedFlag = false;
				openButton.selected = true;
				popupList();
			}
		}
		
		//--------------------------------------------------------------------------
		//
		//  skinPart
		//
		//--------------------------------------------------------------------------
		
		//---------------------
		//labelText
		//---------------------
		private function initLabelText():void
		{
			//labelText.addEventListener(Event.CHANGE,onLabelTextInputHandler);
		}
		
		private function onLabelTextInputHandler(event:Event):void
		{
			inputOpenFlag = true;
			selectedIndex = getMapItemIndex(labelText.text);
		}
		
		//---------------------
		//openButton
		//---------------------
		private function initOpenButton():void
		{
			openButton.addEventListener(MouseEvent.CLICK,onOpenButtonClickHandler);
		}
		
		private function onOpenButtonClickHandler(evt:MouseEvent):void
		{
			isOpen ? close() : open();
		}
		private function destoryOpenButton():void
		{
			openButton.removeEventListener(MouseEvent.CLICK,onOpenButtonClickHandler);
		}
		//---------------------
		//list 
		//---------------------
		/**
		 * 显示列表，当前用户点弹出按钮后，弹出列表供用户
		 * 弹出时点击舞台任何地方聊了列表本身和this 移除列表 
		 */
		protected var list:List;
		
		protected function createPopupList():List
		{
			list = new List();
			list.autoHideScrollbar = true;
			list.itemHeight = itemHeight;
			list.itemRenderer = itemRenderer;
			list.dataProvider = dataProvider;
			list.selectedIndex = selectedIndex;
			list.defaultColor = defaultColor;
			list.defaultAlpha = defaultAlpha;
			list.rolloverColor = rolloverColor;
			list.rolloverAlpha = rolloverAlpha;
			list.selectedColor = selectedColor;
			list.selectedAlpha = selectedAlpha;
			list.addEventListener(Event.CHANGE,onListChangeHandler);
			return list;
		}
		
		protected function onListChangeHandler(evt:Event):void
		{
			selectedIndex = list.selectedIndex;
			close();
		}
		
		protected function popupList():void
		{
			if(isOpen && !stage)return;
			var list:List = createPopupList();
			list.validate();
			var pos:Point = new Point(0,_openPosition == "top" ? -list.height-2 : height+2);
			pos = this.localToGlobal(pos);
			list.x = pos.x;
			list.y = pos.y;
			list.width = width;
			list.scrollToIndex(selectedIndex);
			stage.addChild(list);
			stage.addEventListener(MouseEvent.MOUSE_DOWN,onStageMouseDownHandler);
		}
		
		private function onStageMouseDownHandler(evt:MouseEvent):void
		{
			if(this.hitTestPoint(stage.mouseX,stage.mouseY,true) || list.hitTestPoint(stage.mouseX,stage.mouseY,true))
				return;
			close();
		}
		
		protected function removeList():void
		{
			if(!isOpen || !list)return;
			stage.removeChild(list);
			stage.removeEventListener(MouseEvent.MOUSE_DOWN,onStageMouseDownHandler);
			list.removeEventListener(Event.CHANGE,onListChangeHandler);
			list.destory();
			list = null;
		}
		
		//--------------------------------------------------------------------------
		//
		//  utils
		//
		//--------------------------------------------------------------------------
		//-----------------------------------------------------------------
		//  mapingItem
		//-----------------------------------------------------------------
		/**
		 * 获取在 dataProvider 与对应的 item 索引
		 * @param value
		 * @return 
		 * 
		 */
		private function getMapItemIndex(value:String):int
		{
			var index:int = -1;
			for(var i:int,len:int=dataProvider.length;i<len;i++)
			{
				index = dataProvider[i][labelField].indexOf(value);
				if(index == 0)
					return index;
			}
			return -1;
		}
		//-----------------------------------------------------------------
		//  DefaultSkinDrawer
		//-----------------------------------------------------------------
		override public function get DefaultSkinDrawer():Class
		{
			return ComboBoxSkin;
		}
	}
}